using Unity.Burst.Intrinsics;
using Unity.Entities;

namespace Game.Core
{
    public unsafe partial struct PropertyModifyJob : IJobChunk
    {
        public BufferTypeHandle<PropertyModifier> PropertyModifierTypeHandle;
        public ComponentTypeHandle<PropertyData> PropertyDataTypeHandle;
        public ComponentTypeHandle<Attackable> AttackableTypeHandle;
        public ComponentTypeHandle<Damageable> DamageableTypeHandle;
        public ComponentTypeHandle<Movable> MovableTypeHandle;

        public void Execute(in ArchetypeChunk batch, int batchIndex, bool useEnabledMask, in v128 chunkEnabledMask)
        {
            bool hasPropertyData = batch.Has(PropertyDataTypeHandle);
            bool hasAttackable = batch.Has(AttackableTypeHandle);
            bool hasDamageable = batch.Has(DamageableTypeHandle);
            bool hasMovable = batch.Has(MovableTypeHandle);

            var modifiersAccessor = batch.GetBufferAccessor(PropertyModifierTypeHandle);
            int count = batch.Count;
            for (int i = 0; i < count; i++)
            {
                var modifiers = modifiersAccessor[i];
                for (int j = 0; j < modifiers.Length; j++)
                {
                    var modifier = modifiers[j];
                    
                    if (hasPropertyData)
                    {
                        var ptrArray = batch.GetComponentDataPtrRW(ref PropertyDataTypeHandle);
                        var ptrData = (PropertyData*)ptrArray + i;
                        PropertyUtil.ModifyProperty(ptrData, &modifier);
                    }
                    
                    if (hasAttackable)
                    {
                        var ptrArray = batch.GetComponentDataPtrRW(ref AttackableTypeHandle);
                        var ptrAttackable = (Attackable*)ptrArray + i;
                        PropertyUtil.ModifyProperty(ptrAttackable, &modifier);
                    }
                    
                    if (hasDamageable)
                    {
                        var ptrArray = batch.GetComponentDataPtrRW(ref DamageableTypeHandle);
                        var ptrDamageable = (Damageable*)ptrArray + i;
                        PropertyUtil.ModifyProperty(ptrDamageable, &modifier);
                    }

                    if (hasMovable)
                    {
                        var ptrArray = batch.GetComponentDataPtrRW(ref MovableTypeHandle);
                        var ptrMovable = (Movable*)ptrArray + i;
                        PropertyUtil.ModifyProperty(ptrMovable, &modifier); 
                    }
                }
                modifiers.Clear();
            }
        }
    }
}